package com.chenbei.system.aspectj;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import com.chenbei.common.util.IPUtil;
import com.chenbei.common.domain.vo.IPRegionInfo;
import com.chenbei.system.domain.SysUser;
import com.chenbei.system.domain.SysOperationLog;
import com.chenbei.system.service.ISysUserService;
import com.chenbei.system.service.ISysOperationLogService;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Aspect
@Component
public class OperationLogAspectj {

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Autowired
    private ISysUserService adminUserService;

    @Autowired
    private ISysOperationLogService operationLogService;

    @Pointcut("@annotation(com.chenbei.common.annotation.OperationLog)")
    public void operationLog() {}

    @Around(value = "operationLog()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Object proceed = pjp.proceed();
        stopWatch.stop();
        saveOperationLog(pjp, stopWatch.getTotalTimeMillis());
        return proceed;
    }

    //保存操作日志
    public void saveOperationLog(ProceedingJoinPoint pjp, long caseTime) {
        SysOperationLog operationLog = new SysOperationLog();
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        Method method = methodSignature.getMethod();
        if (method != null) {
            com.chenbei.common.annotation.OperationLog annotation = method.getAnnotation(com.chenbei.common.annotation.OperationLog.class);
            operationLog.setModuleName(annotation.moduleName());
            operationLog.setEventName(annotation.eventName());
        }

        operationLog.setIp(IPUtil.getIpAddr(httpServletRequest));
        IPRegionInfo regionByIP = IPUtil.getRegionByIP(operationLog.getIp());
        operationLog.setRegion("");
        if (regionByIP != null) {
            operationLog.setRegion(regionByIP.getProvince() + regionByIP.getCity());
        }

        operationLog.setUserId(0L);
        operationLog.setUsername("匿名用户");
        try {
            long loginId = StpUtil.getLoginIdAsLong();
            SysUser sysUser = adminUserService.getById(loginId);
            operationLog.setUserId(sysUser.getId());
            operationLog.setUsername(sysUser.getUsername());
        } catch (NotLoginException ignored) {}


        operationLog.setCostTime(caseTime);
        operationLog.setCreateTime(LocalDateTime.now());
        operationLogService.save(operationLog);
    }
}
